package com.czf.easyexcel.listener;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.czf.easyexcel.dao.BatchMapper;
import com.czf.easyexcel.entity.Student;
import com.czf.easyexcel.entity.Teacher;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Component
/*
* 有个很重要的点 Listener 不能被spring管理，要每次读取excel都要new,然后里面用到spring可以构造方法传进去
* 不能被spring管理，那么监听器就不可以被依赖注入，可以写个带dao接口的构造函数，然后通过其它层注入（本例是在控制层注入的）

 * */
public class customizeListenner<T> extends AnalysisEventListener<T> {
    /**
     * 每隔5条存储数据库，实际使用中可以3000条，然后清理list ，方便内存回收
     */
    private static final int BATCH_COUNT = 5;
    List<T> list = new ArrayList<T>();
    private String sheetName;
    private BatchMapper batchMapper;


    public customizeListenner(BatchMapper batchMapper) {
        this.batchMapper = batchMapper;
    }

    @Override
    public void invoke(T t, AnalysisContext analysisContext) {
        list.add(t);
        sheetName = analysisContext.readSheetHolder().getSheetName();
        // 达到BATCH_COUNT了，需要去存储一次数据库，防止数据几万条数据在内存，容易OOM
        if (list.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成清理 list
            list.clear();
        }

    }


    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        // 这里也要保存数据，确保最后遗留的数据也存储到数据库
        if (list.size() != 0) {
            saveData();
        }
        log.info("所有数据解析完成！");
    }

    /**
     * 加上存储数据库
     */
    private void saveData() {
        log.info("{}条数据，开始存储数据库！", list.size());
        if (sheetName.equals("student")) {
            List<Student> students = new ArrayList<>();
            for (T t : list) {
                Student s = (Student) t;
                log.info(s.getName());
                students.add(s);
            }
            batchMapper.BatchSaveStudent(students);
        } else {
            if (sheetName.equals("teacher")) {
                List<Teacher> teachers = new ArrayList<>();
                for (T t : list) {
                    Teacher tea = (Teacher) t;
                    log.info(tea.getTeacher_name());
                    teachers.add(tea);
                }
                batchMapper.BatchSaveTeacher(teachers);
            }
            log.info("存储数据库成功！");
        }
    }
}
